#include "sysflash.h"

int flash_program(uint32_t start_addr,uint32_t *data,uint16_t size) {
    
    uint32_t addr = start_addr;
	FLASH_Unlock();
	
	FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
    
    int i = 0;
    while(addr < (start_addr + size)) {
		FLASH_ProgramWord(addr,data[i]);
        addr += 4;
        i++;
		FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
    }
	
    FLASH_Lock();
    return 0;
}
#if 0
int crc_flash(uint32_t start_addr,uint32_t size,uint16_t crc_value) {

    uint8_t *p = (uint8_t*)start_addr;

    uint32_t len = size/4 -1;
    uint8_t temp[4] = {0};
    
    rcu_periph_clock_enable(RCU_PMU);
    rcu_periph_clock_enable(RCU_CRC);
    
    CRC_CTL = CRC_CTL_RST;
    do {
        temp[0] = *(p+3);
        temp[1] = *(p+2);
        temp[2] = *(p+1);
        temp[3] = *p;
        CRC_DATA = * (uint32_t *)temp;
        p += 4;
    } while (len--);
    
    if((CRC_DATA & 0xFFFF) != (uint32_t)crc_value) {
        return -1;
    } else {
        return 0;
    }
}
#endif

void erase_page(uint16_t page_num, uint16_t page_count) {
    
    uint16_t i;

    uint32_t base_address = 0x08000000;
    uint32_t page_address = base_address + (FMC_PAGE_SIZE * page_num);

    FLASH_Unlock();
	FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
    
    for(i = 0; i < page_count; i++){
        FLASH_ErasePage(page_address);
        page_address = page_address + FMC_PAGE_SIZE;
		FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
    }
    
    FLASH_Lock();
}

void read_flash(uint32_t address, uint8_t *data, uint8_t data_num) {
    uint8_t i;
    uint8_t *p = (uint8_t *)address;
    for(i = 0; i < data_num; i++) {
        data[i] = *p;
        p++;
    }
}
